package com.dcm.live.service.impl;

import cn.hutool.system.UserInfo;
import com.dcm.common.constant.LiveConstant;
import com.dcm.common.enums.LikeStatusEnum;
import com.dcm.common.exception.MyException;
import com.dcm.common.service.RedisService;
import com.dcm.common.utils.RedisKeyUtils;
import com.dcm.live.dto.LikedCountDto;
import com.dcm.live.entity.LiveRoomEntity;
import com.dcm.live.entity.UserLikeEntity;
import com.dcm.live.mapper.LikedMapper;
import com.dcm.live.service.LikedService;
import com.dcm.live.service.LiveRoomService;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.Cursor;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * [一句话描述该类的功能]
 *
 * @author : [pengrongsheng]
 * @createTime : [2021/4/8]
 */
@Service
public class LikedServiceImpl implements LikedService {

    @Autowired
    private LikedMapper likedMapper;

    @Autowired
    private RedisService redisService;

    @Autowired
    private LiveRoomService roomService;

    /**
     * 保存到数据库
     *
     * @param userLikeEntity 保存的点赞记录
     * @return
     */
    @Override
    public UserLikeEntity save(UserLikeEntity userLikeEntity) {
        if (userLikeEntity.getId() == null) {
            likedMapper.insert(userLikeEntity);
        } else {
            likedMapper.update(userLikeEntity);
        }
        return userLikeEntity;
    }

    @Override
    public List<UserLikeEntity> getLikedListByLikedUserId(Long likedUserId) {
        return likedMapper.getLikedListByLikedUserId(likedUserId);
    }

    @Override
    public List<UserLikeEntity> getLikedListByLikedPostId(Long likedPostId) {
        return likedMapper.getLikedListByLikedPostId(likedPostId);
    }

    /**
     * 把redis中的数据持久化到DB
     */
    @Override
    public void transLikedFromRedis2db() {
        List<UserLikeEntity> list = getLikedDataFromRedis();
        for (UserLikeEntity like : list) {

            UserLikeEntity ul = likedMapper.findByUidAndId(like.getLikedUserId(), like.getLikedPostId());
            if (ul == null) {
                save(like);
            } else {
                ul.setStatus(like.getStatus());
                save(ul);
            }
        }
    }

    @Override
    public void transLikedCountFromRedis2db() {
        List<LikedCountDto> list = getLikedCountFromRedis();
        for (LikedCountDto dto : list) {
            LiveRoomEntity room = roomService.findRoomByUserId(dto.getLikedUserId());
            if (room != null) {
                Integer likeNum = room.getLikeNum() + dto.getCount();
                room.setLikeNum(likeNum);
                //更新点赞数量
                roomService.updateRoom(room);
            }
        }
    }

    /**
     * redis操作
     *
     * @param uid 主播id
     * @param pid 用户id
     */
    @Override
    public void saveLiked2Redis(Long uid, Long pid) {
        redisService.hSet(LiveConstant.MAP_KEY_USER_LIKED, RedisKeyUtils.getLikedKey(uid, pid), LikeStatusEnum.LIKE.getCode());
        incrementCount(uid);
    }

    @Override
    public void unLikedFromRedis(Long uid, Long pid) {
        redisService.hSet(LiveConstant.MAP_KEY_USER_LIKED, RedisKeyUtils.getLikedKey(uid, pid), LikeStatusEnum.UNLIKE.getCode());
        decrementCount(uid);
    }

    @Override
    public void incrementCount(Long uid) {
        String mapKey = LiveConstant.MAP_KEY_USER_LIKED_COUNT;
        String uidKey = uid + "";
        Object o = redisService.hGet(mapKey, uidKey);
        if (o == null) {
            redisService.hSet(mapKey, uidKey, 1L);
        } else {
            redisService.hIncr(mapKey, uidKey, 1L);
        }
    }

    @Override
    public void decrementCount(Long uid) {
        String mapKey = LiveConstant.MAP_KEY_USER_LIKED_COUNT;
        String uidKey = uid + "";
        Object o = redisService.hGet(mapKey, uidKey);
        if (o == null) {
            throw new MyException("无此用户！");
        } else {
            redisService.hIncr(mapKey, uidKey, -1L);
        }
    }

    @Override
    public List<UserLikeEntity> getLikedDataFromRedis() {
        Cursor<Map.Entry<Object, Object>> cursor = redisService.hScan(LiveConstant.MAP_KEY_USER_LIKED);
        ArrayList<UserLikeEntity> list = new ArrayList<>();
        while (cursor.hasNext()) {
            Map.Entry<Object, Object> entry = cursor.next();
            String key = (String) entry.getKey();
            //分离出 likedUserId，likedPostId
            String[] split = key.split("::");
            Long likedUserId = Long.parseLong(split[0]);
            Long likedPostId = Long.parseLong(split[1]);
            Integer value = (Integer) entry.getValue();
            //组成 UserLikeEntity 对象 存入 list
            UserLikeEntity userLikeEntity = new UserLikeEntity(likedUserId, likedPostId, value);
            list.add(userLikeEntity);

            redisService.hDel(LiveConstant.MAP_KEY_USER_LIKED, key);
        }
        return list;
    }

    @Override
    public List<LikedCountDto> getLikedCountFromRedis() {
        Cursor<Map.Entry<Object, Object>> cursor = redisService.hScan(LiveConstant.MAP_KEY_USER_LIKED_COUNT);
        List<LikedCountDto> list = new ArrayList<>();
        while (cursor.hasNext()) {
            Map.Entry<Object, Object> map = cursor.next();
            //将点赞数量存储在 LikedCountDto
            String key = (String) map.getKey();
            Long id = Long.parseLong(key);
            LikedCountDto dto = new LikedCountDto(id, (Integer) map.getValue());
            list.add(dto);
            //从Redis中删除这条记录
            redisService.hDel(LiveConstant.MAP_KEY_USER_LIKED_COUNT, key);
        }
        return list;
    }
}
